`timescale 1 ns / 1 ps
/*------------------- include --------------------*/

/*---------------------------------------------*/

`define CLOCK_FREQ_MHz 50.0   //系统主频 MHz

module debug; 

reg clk ;

//生成时钟
parameter NCLK = 1000/`CLOCK_FREQ_MHz; 
initial begin
	clk=0;
	forever clk=#(NCLK/2) ~clk; 
end 

initial begin
    $dumpfile("wave.vcd");
    $dumpvars(0, debug);   //dumpvars(深度, 实例化模块1，实例化模块2，.....)
end


reg [7:0] a , b ,result ; 
reg cin , cout ;
initial begin
    cin = 1 ;
    a = 8'h8e; 
    b = 8'hb5 ;
    {cout , result} = add_alu(a,b,cin , 2'b01);
    $display("a=%d",a) ;
    $display("b=%d",b) ;
    $display("result=%d",result) ;
    $display("cout=%d",cout) ;

    $display("--------------------------") ;
    {cout , result} = add_alu(a,b,cin , 2'b10);
    $display("a=%d",a) ;
    $display("b=%d",b) ;
    $display("result=%d",result) ;
    $display("cout=%d",cout) ;
    repeat(500) @(posedge clk) ;

    $display("%d ns:done",$time);
	$dumpflush;
	$finish;
	$stop;	
end


function [8:0] add_alu( input [7:0] op1 , input [7:0] op2 , input cin ,  input [1:0] op_type ) ;
reg [7:0] addsub ; 
reg addsub_carry ;
reg [8:0] addsub_result ;
reg [7:0] addsub_b ;
begin
    add_alu[8] = 1'b0 ;
    if(op_type == 2'b01) begin // addcy 
        addsub_carry = cin ;
    end else if(op_type == 2'b10) begin   // sub
        addsub_carry = 1'b1;
    end else if(op_type == 2'b11) begin   // subcy 
        addsub_carry = ~cin ; 
    end else 
        addsub_carry = 1'b0 ;   // add 

    addsub_b = ((op_type == 2'b10) || (op_type == 2'b11)) ? ~op2 : op2 ;
    addsub_result = op1 + addsub_b + addsub_carry ;

    if((op_type == 2'b01) || (op_type == 2'b00)) begin // addcy  add 
        add_alu[8] = cin ;
    end  else 
        add_alu[8] = ~addsub_result[8] ;  

    add_alu[7:0] = addsub_result[7:0] ;
end
endfunction 

endmodule
